package cn.boodqian.airreport;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Locale;

import com.google.gson.reflect.TypeToken;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
import cn.boodqian.utils.*;

public class ServerMessageHandler extends Handler {
    public ServerMessageHandler(Activity mParentActivity) {
        super();
        this.mParentActivity = mParentActivity;
    }
    private Activity mParentActivity;
    
    // Whether this is checked by user manually
    // If so, need to ignore server message and to prompt if this is already the newest version
    public boolean mUserCommand = false;
    /* (non-Javadoc)
     * @see android.os.Handler#handleMessage(android.os.Message)
     */
    @Override
    public void handleMessage(Message msg) {
        if( msg.what != GAERequest.MESSAGE_DONE_OK )
            return;

        // For debug purpose
        /*
        msg.obj = "{" + 
        		"\"version\":29,\r\n" + 
        		"\"apk\":\"airreport-v2.1-25-release.apk\",\r\n" + 
        		"\"update-zh\":\"新版本提示\"," + 
        		"\"update\":\"Update Message\"," +
        		"\"message-zh\":\"服务器消息\"," +
        		"\"message\":\"Server Message\"," +
        		"\"message-code\":5" + 
        		"}";
         //*/
        
        HashMap<String,String> map = null;
        try {
            Type type = new TypeToken<HashMap<String,String>>(){}.getType();
            map = GlobalData.gGson.fromJson(msg.obj.toString(), type);
        } catch(Exception e) {
            map = null;
            Log.e(e.getLocalizedMessage());
            e.printStackTrace();
        }
        if(map==null || map.size()==0) {
            Log.w("Received invalid update message");
            return;
        }

        Log.i("Server Message: "+map.toString());

        String locale = Locale.getDefault().getLanguage();
        if( locale.length() >= 2 ) locale = locale.substring(0, 2);
        else locale = "";
        Log.i("Client locale: " + locale);

        long when = System.currentTimeMillis();
        int currentVersion = GlobalData.getVersionCode(mParentActivity);
        int messageVersion = 0;
        int savedLastServerMessageCode = GlobalData.gLastServerMessageCode;
        long savedLastUpdateMessageTime = GlobalData.gLastUpdateMessageTime;
        try{
            messageVersion = Integer.parseInt(map.get("version"));
            Log.i(String.format(java.util.Locale.US, "Server Message rcv, %d (%d)", messageVersion, currentVersion));

            if(currentVersion>messageVersion) return;

            String message = null;
            String title = null;
            int messageCode=0;
            boolean isLatestVersion = ( currentVersion == messageVersion );
            Log.i( String.format("isLatestVersion: %b, mUserCommand: %b", isLatestVersion, mUserCommand ) );

            if( !isLatestVersion ) {
                // When version below, show 'update' field
                title = mParentActivity.getString(R.string.server_update);
                message = map.get("update-" + locale);
                if( message == null )
                    message = map.get("update");
            } else if(  isLatestVersion && !mUserCommand ) {
                // When version matches, show 'message' field
                title = mParentActivity.getString(R.string.server_message);
                message = map.get("message-" + locale);
                if( message == null )
                    message = map.get("message");
                String str = map.get("message-code");
                if(str!=null)
                    messageCode = Integer.parseInt(str);

                Log.i(String.format(java.util.Locale.US, "message-code: old %d new %d", GlobalData.gLastServerMessageCode, messageCode));

                // Only display message with higher code
                if(GlobalData.gLastServerMessageCode >= messageCode) return;
            }
            if(message==null || message.compareTo("")==0) return;

            // Only prompt once a day at most
            // Update the time stamp now so we don't retrieve the update info next time
            GlobalData.gLastUpdateMessageTime = when;
            
            if( !isLatestVersion )
                showUpdateDialog(title, message, map.get("apk") );
            else
                showMessageDialog(title, message);
        } catch (Exception e) {
            if(currentVersion == messageVersion)
                GlobalData.gLastServerMessageCode = savedLastServerMessageCode;
            else
                GlobalData.gLastUpdateMessageTime = savedLastUpdateMessageTime;
            e.printStackTrace();
        } finally {
            if( mUserCommand && currentVersion >= messageVersion ) {
                mUserCommand = false;
                new AlertDialog.Builder(mParentActivity).setTitle(android.R.string.dialog_alert_title)
                .setMessage(R.string.no_update_available)
                .setPositiveButton(R.string.iknow, null)
                .show();
            }
        }
    }

    private void showMessageDialog( String title, String message )
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(mParentActivity).setTitle(title)
                .setMessage(message)
                .setPositiveButton(R.string.iknow, new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        try {
                            dialog.dismiss();
                        } catch( Exception e ) {
					        // In case activity finished before dismiss (several hits seen in crash report)
					        Log.w( "Dismiss exception: " + e.getLocalizedMessage() );
					        return;
					    }
                    }
                });
        AlertDialog dialog = builder.show();
        TextView textView = (TextView) dialog.findViewById(android.R.id.message);
        textView.setTextSize(15);
    }
    private void showUpdateDialog( String title, String message, String apkUrl )
    {

        AlertDialog.Builder builder = new AlertDialog.Builder(mParentActivity).setTitle(title)
                .setMessage(message)
                .setPositiveButton(R.string.check_store, new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Intent.ACTION_VIEW);
                        intent.setData(Uri.parse("market://details?id=cn.boodqian.airreport"));
                        try {
                            mParentActivity.startActivity(intent);
                        } catch(ActivityNotFoundException e) {
                            new AlertDialog.Builder(mParentActivity).setTitle(android.R.string.dialog_alert_title)
                            .setMessage(R.string.no_store_installed)
                            .setPositiveButton(R.string.iknow, null)
                            .show();
                        }
                    }
                });

        if( ! apkUrl.startsWith("http://") )
            apkUrl = GlobalData.gApkHost+apkUrl;
        Log.i("update apk: " + apkUrl);
        final String apk = apkUrl;
        if( apk != null && apk.endsWith(".apk") ) {
            builder.setNegativeButton(R.string.direct_download, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(apk));
                    try {
                        mParentActivity.startActivity(intent);
                    } catch(ActivityNotFoundException e) {
                        new AlertDialog.Builder(mParentActivity).setTitle(android.R.string.dialog_alert_title)
                        .setMessage(R.string.no_browser_installed)
                        .setPositiveButton(R.string.iknow, null)
                        .show();
                    }
                }
            });
        }
        
        builder.setNeutralButton(R.string.remind_later, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    try {
                        dialog.dismiss();
                    } catch( Exception e ) {
                        // In case activity finished before dismiss (several hits seen in crash report)
                        Log.w( "Dismiss exception: " + e.getLocalizedMessage() );
                        return;
                    }
                }
        });
        
        AlertDialog dialog = builder.show();
        TextView textView = (TextView) dialog.findViewById(android.R.id.message);
        textView.setTextSize(15);
    }
}